home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#23 (Aug 87)
/
Dont panic source
/
DON'T PANIC code.c
< prev
next >
Wrap
Text File
|
1987-04-19
|
18KB
|
690 lines
/*
File:
"Don't Panic"
an AppleTalk application
By:
Ty Shipman, Gorilla Software Systems
April 11, 1987
For: General Public using LightSpeed C
(C) Copyright 1987 Ty Shipman
All Rights Resereved.
This notice must appear in all copies. Commerical use of
this code forbidden, without prior written
permission of the author.
*/
#include "MacTypes.h"
#include "DialogMgr.h"
#include "EventMgr.h"
#include "ControlMgr.h"
#include "Appletalk.h"
#include "DON'T PANIC.h"
/* all the globals*/
CurEntity NowEntity; /* the current selected target for request */
char *ErrMess; /* a pointer to a possible error message */
ABRecHandle atpRec; /* handle to the above */
Str255 atpRecBuf; /* to hold request data in */
int RecSocket; /* the socket I receive requests through */
char LUBuffer[2000]; /* my lookup buffer */
int Extractwhere; /* the current place in the extract list */
ABRecHandle myABRecord; /* for my mac reg on net */
EntityName myEntity; /* used to store my name,type,zone on */
char myEBuff[105]; /* this is a wasted space, max is 105 */
ABRecHandle Responce; /* for the responce stuff */
BDSElement RspBDS;
char *BDSmess = "\pI recieved your message, requester";
BDSPtr myBDSPtr; /* used in the request stuff */
BDSElement myBDS; /* used to reference the responce */
char mysBuffer[512]; /* store the responce here */
ABRecHandle SendRec;
/* end of globals */
extern DialogPtr myWindow;
doAlloc()
{
/* this routine will allocate all the records needed */
myABRecord = (ABRecHandle)NewHandle(sizeof(ABusRecord)); /* for my mac reg on net */
Responce = (ABRecHandle)NewHandle(sizeof(ABusRecord));
SendRec = (ABRecHandle)NewHandle(sizeof(ABusRecord));
}
ATCheck()
{
char *PortBUseP; /* a pointer to PortBUse Byte */
char *SPConfigP; /* SerialPortConfiguration byte */
char use,con; /* storage for pointer contence*/
int error;
/* this routine will check to see if the port is set up for
AppleTalk. It will also load the ATP, NBP, and
any other packages necessary for AppleTalk.
*/
CouldDialog(ERRDLOG_ID); /*read into memory*/
PortBUseP = (char *)(PortBUse); /* a pointer to PortBUse Byte */
SPConfigP = (char *)(SPConfig); /* a pointer to SerialPortConfiguration byte*/
use = *PortBUseP; /* get the data */
con = *SPConfigP; /* get the data */
if( (con & 0x0F) > useATalk )
{
ErrMess = "\pSomething wrong with the port(config). Exit now!";
ErrDial(); /* put up error message in dialog */
return(1);
}
if( (use & 0xFF) || ( (use&0x0F) == useATalk) )
{
/* port is currently closed, open as I like or it's AppleTalk*/
if( !(IsMPPOpen()) )
{
if( (error = MPPOpen()) != noErr)
{
ErrMess = "\pSomething wrong with the port(MMP). Exit now, and restart your system!";
ErrDial(); /* put up error message in dialog */
return(1);
}
}
if( !IsATPOpen() )
{
if( (error = ATPLoad()) != noErr)
{
ErrMess = "\pSomething wrong with the port(ATP). Exit now!";
ErrDial(); /* put up error message in dialog */
return(1);
}
*PortBUseP |= 0x04; /* ATP loaded */
*PortBUseP &= 0x7F; /* in use set, set = 0 */
}
if( (error = NBPLoad()) ) /* only on 128 MAC's*/
{
if(error != noErr)
{
ErrMess = "\pSomething wrong with the port(NBP). Exit now!";
ErrDial(); /* put up error message in dialog */
return(1);
}
}
} /* end test on port config and use */
else
{
ErrMess = "\pUse bits not correct";
ErrDial();
return(1);
}
*SPConfigP |= 0x01; /* set for appleTalk */
doAlloc();
return;
}
LookUp()
{
/* This function will lookup everything on the current zone.
*/
long junklong;
Str255 string,jstr;
char *tempstr;
int myNet,myNode;
AddrBlock atpaddrs; /* a filter of who I receive requests through */
EntityName searchEntity; /* who I should search for during lookup */
Handle itemHand;
int type;
Rect SelBox;
int error;
if( atpRec == 0 )
{
/* this is only executed the first time it is called */
atpRec = (ABRecHandle)NewHandle(sizeof(ABusRecord)); /* record for the ReceivedRequest */
RecSocket = MYSOCKET;
atpaddrs.aNet = (int)0; /* wild, all */
atpaddrs.aNode = (Byte)0; /* wild, all */
atpaddrs.aSocket = (Byte)0; /* wild, all */
if( (error = ATPOpenSocket(atpaddrs,&RecSocket)) != noErr)
{
ErrMess = "\pSomething wrong ATPOpenSocket.";
NumToString( (long)error, string);
Pappend(ErrMess,string); /* give me the error number */
ErrDial();
return(1); /* for some error control return 1 else return a 0 */
}
NetReg(); /* register that name and node/socket on net */
if( GetNodeAddress(&myNode,&myNet) != noErr)
{
/* I do this only so I can display it on the screen, not necessary normally */
/* because I have opened the receive socket above I know the
InterNet address.
*/
ErrMess = "\pSomething wrong GetNodeAddress";
ErrDial();
}
junklong = (myNode);
NumToString( junklong, jstr); /* put the node number in a char string */
Pstrcopy(string,jstr);
tempstr = "\p:"; /* just a colon */
Pappend(string,tempstr);
junklong = RecSocket; /* no longer contains a 0 so convert and place in a string*/
NumToString(junklong,jstr);
Pappend(string,jstr); /* add to display string */
tempstr = "\p@";
Pappend(string,tempstr);
junklong = myNet;
NumToString(junklong,jstr);
Pappend(string,jstr); /* add the net number to the display string */
GetDItem(myWindow,MYNUM,&type,&itemHand,&SelBox);
SetIText(itemHand,string); /* display the InterNet Address */
}
/*now that I have my name and node I want to know everyone else */
tempstr = "\p="; /*wild card for obj and type*/
Pstrcopy(searchEntity.objStr,tempstr);
Pstrcopy(searchEntity.typeStr,tempstr);
tempstr ="\p*"; /* wild card for this zone only */
Pstrcopy(searchEntity.zoneStr,tempstr); /* what ever this zone is */
(**myABRecord).nbpProto.nbpEntityPtr = &searchEntity; /* set up filter for search of net */
(**myABRecord).nbpProto.nbpBufPtr = (Ptr)&LUBuffer[0]; /* used internal by NBP */
(**myABRecord).nbpProto.nbpBufSize = sizeof(LUBuffer); /* where the returned names go */
(**myABRecord).nbpProto.nbpDataField = 100; /* about 100 node out there??? */
(**myABRecord).nbpProto.nbpRetransmitInfo.retransInterval = 75; /* in 8 tick counts, 75 = 10 sec*/
(**myABRecord).nbpProto.nbpRetransmitInfo.retransCount = 2; /* set up the retry stuff */
if( (NBPLookup(myABRecord,SYNC) != noErr) )
{
ErrMess = "\pSomething wrong NBPLookup. To many node maybe?";
ErrDial();
}
junklong = (long)(**myABRecord).nbpProto.nbpDataField + 1;
/* the .nbpDataField tells you how may named enities were on the net */
if( junklong > 1)
{
GetDItem(myWindow,DISPLAYB,&type,&itemHand,&SelBox);
HiliteControl(itemHand,0); /*part0, turn on*/
}
NumToString( junklong, string);
GetDItem(myWindow,NUMBER,&type,&itemHand,&SelBox);
SetIText(itemHand,string); /* display how may */
Extractwhere = 1; /* start here on extract */
Receive(0); /* now that someone maybe on the system set up to receive a request */
Receive(1);
Receive(1);
Receive(1);
Receive(1); /* put in a bunch of request receives in the que */
return(0); /* good return */
}
NetReg()
{
/* this routine will register the name, type on the net */
Handle itemHand;
int type;
Rect SelBox;
char *tempstr;
Str255 string;
int error;
/* going to set up the name, type, and zone of this Mac */
GetDItem(myWindow,MYNODE,&type,&itemHand,&SelBox); /*my usr name, set with the chooser */
GetIText(itemHand,&myEntity.objStr); /* put in usr name */
tempstr = "\pGORILLA"; /* a Ty Shipman Type */
Pstrcopy(myEntity.typeStr,tempstr);
tempstr = "\p*"; /* current zone */
Pstrcopy(myEntity.zoneStr,tempstr);
(**myABRecord).nbpProto.nbpEntityPtr = &myEntity; /* set up my name */
(**myABRecord).nbpProto.nbpBufPtr = (Ptr)&myEBuff; /* used internal by NBP */
(**myABRecord).nbpProto.nbpBufSize = sizeof(myEBuff);
(**myABRecord).nbpProto.nbpAddress.aSocket = RecSocket; /* this can not be allocated on the fly, set be opensocket */
(**myABRecord).nbpProto.nbpRetransmitInfo.retransInterval = 7; /* in seconds */
(**myABRecord).nbpProto.nbpRetransmitInfo.retransCount = 1;
/* register the name on the system */
if( (error = NBPRegister(myABRecord,SYNC) ) != noErr)
{
ErrMess = "\pSomething wrong with NBPRegister, try a different name.";
NumToString( (long)error, string);
Pappend(ErrMess,string); /* give me the error number */
ErrDial();
return(1);
}
return(0);
}
Receive(redo)
int redo;
{
/* this routine will place a GetRequest in the Que */
int error;
Str255 tempstr;
if( redo == 0)
{
(**atpRec).atpProto.atpSocket = RecSocket;
(**atpRec).atpProto.atpReqCount = 255; /* all but the length bypte */
(**atpRec).atpProto.atpDataPtr = (Ptr)&atpRecBuf; /* my sting to store message */
}
if( (error = ATPGetRequest(atpRec,ASYNC)) != noErr)
{
ErrMess = "\pSomething wrong ATPGetRequest.";
NumToString( (long)error, tempstr);
Pappend(ErrMess,tempstr);
ErrDial();
return(1);
}
return(0);
}
SendResponce(request)
ABRecHandle request;
{
/* This routine will send a responce to a request from another device.
The socket I want to send the responce to is contained in the
request packet.
*/
int error; /* a temp area */
Str255 tempstr;
SetupRsp(&RspBDS,BDSmess,256); /* this routine will copy the message to the BDS specified */
(**Responce).atpProto.atpSocket = RecSocket; /* send out the socket in which the request was sent to */
(**Responce).atpProto.atpAddress.aNet = (**request).atpProto.atpAddress.aNet; /* contains the requesting address */
(**Responce).atpProto.atpAddress.aNode = (**request).atpProto.atpAddress.aNode;
(**Responce).atpProto.atpAddress.aSocket = (**request).atpProto.atpAddress.aSocket;
(**Responce).atpProto.atpRspBDSPtr = (BDSPtr)&RspBDS; /* pointer to BDS, data should already be in BDS */
(**Responce).atpProto.atpTransID = (**request).atpProto.atpTransID;
(**Responce).atpProto.atpEOM = TRUE; /* only one responce here */
(**Responce).atpProto.atpNumBufs = 1; /* only one buffer envolved here */
(**Responce).atpProto.atpBDSSize = 1;
if( (error = ATPSndRsp(Responce,SYNC)) != noErr)
{
ErrMess = "\pSomething wrong ATPSndRsp.";
NumToString( (long)error, tempstr);
Pappend(ErrMess,tempstr);
ErrDial();
return(1);
}
return(0);
}
SetupRsp(BDS,mess,size)
BDSElement *BDS; /* pointer to BDSElement that I am to use */
char *mess; /* the message I am to copy in */
int size; /* the number of bytes to copy into BDS */
{
BDS->buffSize = mess[0] + 1; /* since there is only one packet, of max 256 bytes, set to size */
BDS->buffPtr = mess; /* set pointer to data to be sent to requester */
/*
.dataSize set by reciever of this packet. i.e. the requester
.userBytes set by sender in ATP.
*/
}
Display()
{
/* this routine will display all nodes/sockets on the screen */
Handle itemHand;
int type;
Rect SelBox;
Str255 currstrg, string;
char *tempstr;
if( ((**myABRecord).nbpProto.nbpDataField) <= 0)
return; /* just incase there is nothing in the lookup */
if( (NBPExtract( (Ptr)&LUBuffer,(**myABRecord).nbpProto.nbpDataField
,Extractwhere,&(NowEntity.CurName),&(NowEntity.CurAddrs)) )
!= noErr)
{
ErrMess = "\pSomething wrong NBPExtract.";
ErrDial();
}
GetDItem(myWindow,SENDB,&type,&itemHand,&SelBox);
HiliteControl(itemHand,0); /*part0, turn on*/
/* has nothing to do with AppleTalk, just so I can display it on the screen */
/* uses the standard display format of name : type @ zone */
Pstrcopy(currstrg,NowEntity.CurName.objStr);
tempstr = "\p:"; /* the seperator for name and type */
Pappend(currstrg,tempstr);
Pappend(currstrg,NowEntity.CurName.typeStr);
tempstr = "\p@"; /* the seperator for name and type */
Pappend(currstrg,tempstr);
Pappend(currstrg,NowEntity.CurName.zoneStr);
GetDItem(myWindow,CNODEIS,&type,&itemHand,&SelBox); /* do the name */
SetIText(itemHand,currstrg);
NumToString( (long)NowEntity.CurAddrs.aNode, string);
Pstrcopy(currstrg,string);
tempstr = "\p•"; /* just some filler */
Pappend(currstrg,tempstr);
NumToString( (long)NowEntity.CurAddrs.aSocket, string);
Pappend(currstrg,string);
GetDItem(myWindow,CNODENUM,&type,&itemHand,&SelBox);
SetIText(itemHand,currstrg);
/* all done with the screen display */
if( (Extractwhere < (**myABRecord).nbpProto.nbpDataField) )
Extractwhere++; /* the next time */
else
Extractwhere = 1; /* reset to beginning of list */
return;
}
Send()
{
/* this routine will send a request that contains the editable
text field of the dialog */
int error;
Str255 tempstr;
Handle itemHand;
int type;
Rect SelBox;
myBDSPtr = (BDSPtr)&myBDS;
myBDSPtr[0]->buffPtr = (Ptr)&mysBuffer[0]; /* buffer that will contain message */
myBDSPtr[0]->buffSize = 512;
GetDItem(myWindow,SENDM,&type,&itemHand,&SelBox);
GetIText(itemHand,(Ptr)&mysBuffer[0]); /* put in message */
(**SendRec).atpProto.atpAddress.aNet = NowEntity.CurAddrs.aNet;
(**SendRec).atpProto.atpAddress.aNode = NowEntity.CurAddrs.aNode;
(**SendRec).atpProto.atpAddress.aSocket = NowEntity.CurAddrs.aSocket; /* setup the target address */
(**SendRec).atpProto.atpReqCount = PLength(mysBuffer);
(**SendRec).atpProto.atpDataPtr = (Ptr)&mysBuffer[0]; /* setup the request data */
(**SendRec).atpProto.atpRspBDSPtr = (BDSPtr)&myBDSPtr;
(**SendRec).atpProto.atpXO = FALSE; /* set to NOT exactly once */
(**SendRec).atpProto.atpTimeOut = 4;
(**SendRec).atpProto.atpRetries = 2;
(**SendRec).atpProto.atpNumBufs = 1; /* one BDS element */
(**SendRec).atpProto.atpNumRsp = 0; /* set to no responces yet */
if( (error = ATPSndRequest(SendRec,ASYNC)) != noErr)
{
ErrMess = "\pSomething wrong ATPSndRequest.";
NumToString( (long)error, tempstr);
Pappend(ErrMess,tempstr);
ErrDial();
return(1);
}
Receive(1); /* post because of when done it will post a request event and
use up one GetRequest() */
return(0); /* no error in this code */
}
DoATNet(ParHan)
ABRecHandle ParHan; /* a handle to the record generated by AT */
{
/* this routine will handle all events generated by the apple talkl
net work. The possible events call include:
*/
Handle itemHand;
int type;
Rect SelBox;
if( ParHan == SendRec)
{
if( (**ParHan).atpProto.atpNumRsp > 0)
{
/* here is where you would process the responce */
}
/* no responce, the responder is out ??? */
}
else if( ParHan == atpRec)
{
GetDItem(myWindow,RECM,&type,&itemHand,&SelBox);
SetIText(itemHand,((**ParHan).atpProto.atpDataPtr) );
SendResponce(ParHan); /* send responce to requester */
}
Receive(1); /* now that a message has come in set up for another */
return(0);
}
CloseAT()
{
/* this routine will clean up the frame and glb area */
int error;
Str255 tempstr;
if( (RecSocket != 0) && (error = ATPCloseSocket(RecSocket) != noErr) ) /* for the receive socket */
{
ErrMess = "\pSomething wrong ATPCloseSocket. ";
NumToString( (long)error, tempstr);
Pappend(ErrMess,tempstr);
ErrDial();
return(1);
}
NBPRemove(&myEntity); /* remove from net */
if( SendRec != 0)
{
ATPReqCancel(SendRec,((Boolean)FALSE)); /* for send socket, async */
}
if( atpRec != 0)
DisposHandle(atpRec);
if( myABRecord != 0)
DisposHandle(myABRecord);
if( Responce != 0)
DisposHandle(Responce);
if( SendRec != 0)
DisposHandle(SendRec);
return(0); /* good return */
}
ErrDial()
{
/* this routine puts up a dialog box with the error in it
the error message is contained in a global
the error dialog stay up until a mouse down occures
*/
Handle itemHand;
int type;
Rect SelBox;
DialogPtr errorWindow;
WindowPtr oldport;
GetPort(&oldport);
errorWindow = GetNewDialog(ERRDLOG_ID,NIL,(WindowPtr)-1);
SetPort(errorWindow);
GetDItem(errorWindow,ERRMESS,&type,&itemHand,&SelBox);
SetIText(itemHand,ErrMess);
FrameRect(&SelBox);
GetDItem(errorWindow,2,&type,&itemHand,&SelBox);
ErrMess = "\pClick Mouse to Continue";
SetIText(itemHand,ErrMess);
do {
} while ( !Button() ); /* just click to make go away */
CloseDialog(errorWindow); /* make go away */
SetPort(oldport);
return;
}
int
PLength(strPtr)
unsigned char *strPtr;
{
/*this routine returns the length of the pascal string*/
return( ((int)strPtr[0] + 1) ); /* the first byte is the length */
}
Pstrcopy(dest,sour)
unsigned char *dest, *sour;
{
dest[0] = 0; /* no string in there */
Pappend(dest,sour);
return(0);
}
Pappend(dest,sour)
unsigned char *dest, *sour;
{
/* this routine will copy the 'C' string at sour to a P string at dest */
/* NOTE: the dest char array should be declared static to insure you don't fucked results */
int loop;
int dlen,slen;
slen = (int)sour[0]; /* the length of the string*/
dlen = (int)dest[0]; /* not include the length byte */
slen = ( (dlen + slen) <= 255) ? slen : 255 - dlen; /* not over the stupid limit */
dest[0] += slen; /* new length of stuff */
dest += dlen; /* get to end of stuff */
sour++; /* get past the length byte */
dest++; /* same */
BlockMove(sour,dest,(long)slen);
return(0);
}